# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# Author     ：skyTree
# version    ：python 3.11
# Description：数据库配置
"""
from datetime import datetime

from . import db
from werkzeug.security import check_password_hash, generate_password_hash


class BaseModel(db.Model):
    __abstract__ = True
    create_time = db.Column(db.DateTime, default=datetime.now(), comment='创建时间')
    update_time = db.Column(db.DateTime, default=datetime.now(), onupdate=datetime.now(), comment='更新时间')


class User(BaseModel, db.Model):
    __tablename__ = 't_user'

    id = db.Column(db.Integer, primary_key=True, comment='用户id')
    name = db.Column(db.String(32), unique=True, nullable=False, comment='用户名称')
    pwd = db.Column(db.String(512), nullable=False, comment='用户密码')
    nick_name = db.Column(db.String(32), comment='用户昵称')
    phone = db.Column(db.String(11), unique=True, comment='用户手机号')
    email = db.Column(db.String(32), comment='用户邮箱')

    rid = db.Column(db.Integer, db.ForeignKey('t_role.id'))

    @property
    def password(self):
        return self.pwd

    @password.setter
    def password(self, t_pwd):
        self.pwd = generate_password_hash(t_pwd)

    def check_password(self, t_pwd):
        return check_password_hash(self.pwd, t_pwd)

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'nick_name': self.nick_name,
            'phone': self.phone,
            'email': self.email,
            'role_name': self.role.name if self.role else ''
        }


trm = db.Table('t_role_menu',
               db.Column('role_id', db.Integer, db.ForeignKey('t_role.id')),
               db.Column('menu_id', db.Integer, db.ForeignKey('t_menu.id'))
               )


class Menu(BaseModel, db.Model):
    __tablename__ = 't_menu'
    id = db.Column(db.Integer, primary_key=True, comment='菜单id')
    name = db.Column(db.String(32), unique=True, nullable=False, comment='菜单名称')
    level = db.Column(db.Integer, comment='菜单等级')
    path = db.Column(db.String(32), comment='菜单路径')
    pid = db.Column(db.Integer, db.ForeignKey('t_menu.id'))

    children = db.relationship('Menu')
    roles = db.relationship('Role', secondary=trm, back_populates='menus')

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'level': self.level,
            'path': self.path,
            'pid': self.pid,
        }

    def get_child_list(self):
        obj_child = self.children
        data = []
        for c in obj_child:
            data.append(c.to_dict())
        return data


class Role(BaseModel, db.Model):
    __tablename__ = 't_role'
    id = db.Column(db.Integer, primary_key=True, comment='角色id')
    name = db.Column(db.String(32), unique=True, nullable=False, comment='角色名称')
    desc = db.Column(db.String(128), comment='角色名称')

    users = db.relationship('User', backref='role')
    menus = db.relationship('Menu', secondary=trm, back_populates='roles')

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'desc': self.desc,
            'menu': self.get_menu_list()
        }

    def get_menu_list(self):
        menu_list = []
        menu_sort = sorted(self.menus, key=lambda x: x.id)
        for m in menu_sort:
            if m.level == 1:
                first_dict = m.to_dict()
                first_dict['children'] = []
                for s in menu_sort:
                    if s.level == 2 and s.pid == m.id:
                        first_dict['children'].append(s.to_dict())
                menu_list.append(first_dict)
        return menu_list


class Category(db.Model):
    __tablename__ = 't_category'
    id = db.Column(db.Integer, primary_key=True, comment='分类id')
    name = db.Column(db.String(32), nullable=False, comment='分类名称')
    level = db.Column(db.Integer, comment='分类等级')

    pid = db.Column(db.Integer, db.ForeignKey('t_category.id'))
    children = db.relationship('Category')
    attrs = db.relationship('Attribute', backref='category')

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'level': self.level,
            'pid': self.pid
        }


class Attribute(db.Model):
    __tablename__ = 't_attribute'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32), comment='属性名称')
    val = db.Column(db.String(255), comment='属性值')
    _type = db.Column(db.Enum('static', 'dynamic'), comment='属性类型')
    cid = db.Column(db.Integer, db.ForeignKey('t_category.id'))

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'val': self.val,
            'cid': self.cid,
            'type': self._type,
        }


class Goods(db.Model):
    __tablename__ = 't_goods'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(512), comment='商品名称')
    price = db.Column(db.Float, comment='商品价格')
    number = db.Column(db.Integer, comment='商品数量')
    introduce = db.Column(db.Text, comment='商品介绍')
    big_log = db.Column(db.String(256), comment='商品大图')
    small_log = db.Column(db.String(256), comment='商品小图')
    state = db.Column(db.Integer, comment='商品状态')  # 0未通过 1审核中 2已审核
    is_promote = db.Column(db.Integer, comment='是否畅销')
    hot_number = db.Column(db.Integer, comment='热卖数量')
    weight = db.Column(db.Integer, comment='商品重量')

    cid_one = db.Column(db.Integer, db.ForeignKey('t_category.id'))
    cid_two = db.Column(db.Integer, db.ForeignKey('t_category.id'))
    cid_three = db.Column(db.Integer, db.ForeignKey('t_category.id'))

    category = db.relationship('Category', foreign_keys=[cid_three])

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'price': self.price,
            'number': self.number,
            'introduce': self.introduce,
            'big_log': self.big_log,
            'small_log': self.small_log,
            'state': self.state,
            'is_promote': self.is_promote,
            'hot_number': self.hot_number,
            'weight': self.weight,
            'cid_one': self.cid_one,
            'cid_two': self.cid_two,
            'cid_three': self.cid_three
        }


class Pictrue(db.Model):
    __tablename__ = 't_pictrue'
    id = db.Column(db.Integer, primary_key=True)
    path = db.Column(db.String(512), comment='图片名称')
    gid = db.Column(db.Integer, db.ForeignKey('t_goods.id'))


class GoodsAttr(db.Model):
    __tablename__ = 't_goods_attr'
    gid = db.Column(db.Integer, db.ForeignKey('t_goods.id'), primary_key=True)
    aid = db.Column(db.Integer, db.ForeignKey('t_attribute.id'), primary_key=True)
    val = db.Column(db.String(255), comment='属性值')
    _type = db.Column(db.Enum('static', 'dynamic'), comment='属性类型')


class Order(BaseModel, db.Model):
    __tablename__ = 't_order'
    id = db.Column(db.Integer, primary_key=True)
    uid = db.Column(db.Integer, db.ForeignKey('t_user.id'))
    price = db.Column(db.Float, comment='订单价格')
    number = db.Column(db.Integer, comment='订单数量')
    pay_status = db.Column(db.Integer, comment='订单支付状态')  # 0没支付，1已支付
    is_send = db.Column(db.Integer, comment='订单是否发送')  # 0没发送，1已发送
    fapiao_title = db.Column(db.String(32), comment='订单发票标题')
    fapiao_company = db.Column(db.String(128), comment='订单发票价格')
    fapiao_content = db.Column(db.String(512), comment='订单发票内容')
    addrs = db.Column(db.String(512), comment='订单地址')

    user = db.relationship('User', foreign_keys=[uid])
    order_details = db.relationship('OrderDetail', backref='order')
    express = db.relationship('Express', backref='order')

    def to_dict(self):
        return {
            'id': self.id,
            'uid': self.uid,
            'uname': self.user.name,
            'price': self.price,
            'number': self.number,
            'pay_status': self.pay_status,
            'is_send': self.is_send,
            'fapiao_title': self.fapiao_title,
            'fapiao_company': self.fapiao_company,
            'fapiao_content': self.fapiao_content,
            'addrs': self.addrs,
        }


class OrderDetail(BaseModel, db.Model):
    __tablename__ = 't_order_detail'
    id = db.Column(db.Integer, primary_key=True)
    oid = db.Column(db.Integer, db.ForeignKey('t_order.id'), primary_key=True)
    gid = db.Column(db.Integer, db.ForeignKey('t_goods.id'), primary_key=True)
    number = db.Column(db.Integer, comment='订单数量')
    price = db.Column(db.Float, comment='订单价格')
    total_price = db.Column(db.Float, comment='订单总价格')


class Express(BaseModel, db.Model):
    __tablename__ = 't_express'
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(64), comment='订单详情')
    update_time = db.Column(db.String(32), comment='修改时间')
    oid = db.Column(db.Integer, db.ForeignKey('t_order.id'))

    def to_dict(self):
        return {
            'id': self.id,
            'content': self.content,
            'update_time': self.update_time,
            'oid': self.oid,
        }
